package com.wzxy.wzinfo.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.wzxy.wzinfo.entiry.NewsIntroduce;
import com.wzxy.wzinfo.entiry.User;

import org.springframework.data.jpa.domain.Specification;

public class QueryParamUtil{

	/**
	 * 动态自动设置查找参数 当属性为自定义对象且查询需要时无法使用
	 * @param t 参数对象
	 * @return
	 */
	public static<T> Specification<T> getDynamicParamByReflex(final T t){
		return new Specification<T>() {
	         @Override
	         public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
	        	List<Predicate> predicates = new ArrayList<Predicate>();
	        	Class clazz = t.getClass();
	     		/*
	     	     * 得到类中的所有属性集合 
	     	     */  
	     	    Field[] fs = clazz.getDeclaredFields();
	     	    for (Field field : fs) {
	     			try {
	     				field.setAccessible(true);//设置属性可访问
	     				if(field.get(t)!=null&&isJavaClass(field.getType())){
	     					predicates.add(cb.equal(root.get(field.getName()),field.get(t)));
	     					System.out.println("属性名："+field.getName()+"  "+"属性值："+field.get(t));
	     				}else{
	     					System.out.println("属性名："+field.getName()+" 属性值为空或不是java类型......");
	     				}
	     			} catch (IllegalArgumentException e) {
	     				// TODO Auto-generated catch block
	     				e.printStackTrace();
	     			} catch (IllegalAccessException e) {
	     				// TODO Auto-generated catch block
	     				e.printStackTrace();
	     			}
	     		}
	             return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
	         }
	     };
	}
	
	/**
	 * 判断一个类是JAVA类型还是用户定义类型
	 * @param clz
	 * @return
	 */
	public static boolean isJavaClass(Class<?> clz) {   
		return clz != null && clz.getClassLoader() == null;   
	}
	
	/**
	 * 动态设置查找参数
	 * 当属性为自定义对象且查询需要时可使用
	 * @param user
	 * @return
	 */
	public static Specification<User> getSpec(final User user) {
	     return new Specification<User>() {
	         @Override
	         public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
	        	 List<Predicate> predicates = new ArrayList<Predicate>();
	        	 if(user.getId()!=null) {
	            	 predicates.add(cb.equal(root.get("id"),user.getId())); 
	             }
	             if(user.getUsername()!=null) {
	            	 predicates.add(cb.equal(root.get("username"),user.getUsername())); 
	             }
	             if(user.getPassword()!=null) {
	            	 predicates.add(cb.equal(root.get("password"),user.getPassword())); 
	             }
	             if(user.getType()!=null) {
	            	 predicates.add(cb.equal(root.get("type"),user.getType())); 
	             }
	             if(user.getCreationTime()!=null) {
	            	 predicates.add(cb.equal(root.get("creationTime"),user.getCreationTime())); 
	             }
	             return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
	         }
	     };
	 }
	
	
	/**
	 * 动态设置查找参数
	 * 当属性为自定义对象且查询需要时可使用
	 * @param newsIntroduce 
	 * @param startState 按状态查询是需要,不需要状态时置null
	 * @param endState 按状态查询是需要,不需要状态时置null
	 * @return
	 */
	public static Specification<NewsIntroduce> getSpec(final NewsIntroduce newsIntroduce,final Integer startState,final Integer endState) {
	     return new Specification<NewsIntroduce>() {
	         @Override
	         public Predicate toPredicate(Root<NewsIntroduce> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
	        	 List<Predicate> predicates = new ArrayList<Predicate>();
	        	 if(newsIntroduce.getId()!=null) {
	            	 predicates.add(cb.equal(root.get("id"),newsIntroduce.getId())); 
	             }
	             if(newsIntroduce.getProvideId()!=null) {
	            	 predicates.add(cb.equal(root.get("provideId"),newsIntroduce.getProvideId())); 
	             }
	             if(newsIntroduce.getProvide()!=null&&newsIntroduce.getProvide().getUsername()!=null) {
	            	 predicates.add(cb.equal(root.get("provide").get("username"),newsIntroduce.getProvide().getUsername())); 
	             }
	             if(endState!=null){
	            	 predicates.add(cb.between(root.get("state").as(Integer.class), startState==null?-1:startState,endState)); 
	             }
	             return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
	         }
	     };
	 }
	
	/**
	 * 动态设置模糊查询查找参数
	 * 当属性为自定义对象且查询需要时可使用
	 * @param newsIntroduce 
	 * @param startState 按状态查询是需要,不需要状态时置null
	 * @param endState 按状态查询是需要,不需要状态时置null
	 * @return
	 */
	public static Specification<NewsIntroduce> getLikeSpec(final NewsIntroduce newsIntroduce,final Integer startState,final Integer endState) {
	     return new Specification<NewsIntroduce>() {
	         @Override
	         public Predicate toPredicate(Root<NewsIntroduce> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
	        	 List<Predicate> predicates = new ArrayList<Predicate>();
	        	 
	        	 if(newsIntroduce.getProvideId()!=null) {
	            	 predicates.add(cb.equal(root.get("provideId"),newsIntroduce.getProvideId())); 
	             }
	             if(newsIntroduce.getProvide()!=null&&newsIntroduce.getProvide().getUsername()!=null) {
	            	 predicates.add(cb.equal(root.get("provide").get("username"),newsIntroduce.getProvide().getUsername())); 
	             }
	        	 
	        	 if(endState!=null){
	            	 predicates.add(cb.between(root.get("state").as(Integer.class), startState==null?-1:startState,endState)); 
	             }
	        	 
	             if(newsIntroduce.getTitle()!=null) {
	            	 predicates.add(cb.like(root.get("title").as(String.class),"%" + newsIntroduce.getTitle() + "%")); 
	             }
	             if(newsIntroduce.getIntroduce()!=null) {
	            	 predicates.add(cb.like(root.get("introduce").as(String.class),"%" + newsIntroduce.getIntroduce() + "%")); 
	             }
	             if(newsIntroduce.getURL()!=null) {
	            	 predicates.add(cb.like(root.get("URL").as(String.class),"%" + newsIntroduce.getURL()+ "%")); 
	             }
	             return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
	         }
	     };
	 }
	
	
	/**
	 * 更新参数设置
	 * @param t
	 * @param t1
	 * @return
	 */
	public static<T> T updateParam(T t,T t1){
		
		Class clazz = t.getClass();
 		/*
 	     * 得到类中的所有属性集合 
 	     */  
 	    Field[] fs = clazz.getDeclaredFields();
 	    for (Field field : fs) {
 			try {
 				field.setAccessible(true);//设置属性可访问
 				if(field.get(t)!=null&&isJavaClass(field.getType())){
 					Field f = t1.getClass().getDeclaredField(field.getName());
 					f.setAccessible(true);
 					f.set(t1, field.get(t));
 				}
 			} catch (Exception e) {
 				e.printStackTrace();
 			} 
 		}
		return t1;
	}
}
